package submarinebattle;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/** 游戏窗口 */
public class World extends JPanel { //2.
    /** 窗口的宽 */
    public static final int WIDTH = 641;
    /** 窗口的高 */
    public static final int HEIGHT = 479;

    /** 运行状态 */
    public static final int RUNNING = 0;
    /** 暂停状态 */
    public static final int PAUSE = 1;
    /** 游戏结束状态 */
    public static final int GAME_OVER = 2;
    private int state = RUNNING;

    //如下这一堆对象为窗口中所显示的那堆对象
    private Battleship ship = new Battleship(); //战舰对象
    private SeaObject[] submarines = {};        //潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)数组对象
    private Mine[] mines = {};                  //水雷数组对象
    private Bomb[] bombs = {};                  //炸弹数组对象

    // 生成潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)对象
    private SeaObject nextSubmarine(){
        Random rand = new Random(); //随机数对象
        int type = rand.nextInt(20); //0到19的
        if(type<10){ //0到9时，返回侦察潜艇对象
            return new ObserveSubmarine();
        }else if(type<16){ //10到15时，返回鱼雷潜艇对象
            return new TorpedoSubmarine();
        }else{ //16到19时，返回水雷潜艇对象
            return new MineSubmarine();
        }
    }

    private int subEnterIndex = 0; //潜艇入场计数

    private void submarineEnterAction(){
        subEnterIndex++; //每10毫秒增1
        if(subEnterIndex%40==0){ //每400(40*10)毫秒走一次
            SeaObject obj = nextSubmarine(); //获取潜艇对象
            submarines = Arrays.copyOf(submarines,submarines.length+1); //扩容
            submarines[submarines.length-1] = obj; //将obj添加到最后一个元素上
        }
    }

    private int mineEnterIndex = 0; //水雷入场计数
    /** 水雷入场 */
    private void mineEnterAction(){ //每10毫秒走一次
        mineEnterIndex++; //每10毫秒增1
        if(mineEnterIndex%100==0){ //每1000(100*10)毫秒走一次
            for(int i=0;i<submarines.length;i++){ //遍历所有潜艇
                if(submarines[i] instanceof MineSubmarine){ //若潜艇为水雷潜艇类型
                    MineSubmarine ms = (MineSubmarine)submarines[i]; //将潜艇强转为水雷潜艇类型
                    Mine obj = ms.shootMine(); //获取水雷对象
                    mines = Arrays.copyOf(mines,mines.length+1); //扩容
                    mines[mines.length-1] = obj; //将obj添加到最后一个元素上
                }
            }
        }
    }

    // 海洋对象移动
    private void moveAction(){ //每10毫秒走一次
        for(int i=0;i<submarines.length;i++){ //遍历所有潜艇
            submarines[i].move(); //潜艇移动
        }
        for(int i=0;i<mines.length;i++){ //遍历所有水雷
            mines[i].move(); //水雷移动
        }
        for(int i=0;i<bombs.length;i++){ //遍历所有炸弹
            bombs[i].move(); //炸弹移动
        }
    }

    //删除越界海洋对象----避免内存泄漏
    private void outOfBoundsAction(){
        for(int i=0;i<submarines.length;i++){
            if(submarines[i].isOutOfBounds() || submarines[i].isDead()){
                submarines[i] = submarines[submarines.length-1];
                submarines = Arrays.copyOf(submarines,submarines.length-1);
            }
        }

        for(int i=0;i<mines.length;i++){
            if(mines[i].isOutOfBounds() || mines[i].isDead()){
                mines[i] = mines[mines.length-1];
                mines = Arrays.copyOf(mines,mines.length-1);
            }
        }

        for(int i=0;i<bombs.length;i++){
            if(bombs[i].isOutOfBounds() || bombs[i].isDead()){
                bombs[i] = bombs[bombs.length-1];
                bombs = Arrays.copyOf(bombs,bombs.length-1);
            }
        }
    }

    private int score = 0;
    // 炸弹与潜艇的碰撞
    private void bombBangAction(){
        for(int i=0;i<bombs.length;i++){
            Bomb b = bombs[i];
            for(int j=0;j<submarines.length;j++){
                SeaObject s = submarines[j];
                if(b.isLive() && s.isLive() && b.isHit(s)){
                    s.goDead();
                    b.goDead();
                    if(s instanceof EnemyScore){
                        EnemyScore es = (EnemyScore)s;
                        score += es.getScore();
                    }
                    if(s instanceof EnemyLife){
                        EnemyLife el = (EnemyLife)s;
                        int num = el.getLife();
                        ship.addLife(num);
                    }
                }
            }
        }
    }

    //水雷与战舰的碰撞/
    private void mineBangAction(){
        for(int i=0;i<mines.length;i++){
            Mine m = mines[i];
            if(m.isLive() && ship.isLive() && m.isHit(ship)){
                m.goDead();
                ship.subtractLife();
            }
        }
    }

    ///检测游戏结束
    private void checkGameOverAction(){
        if(ship.getLife()<=0){
            state = GAME_OVER;
        }
    }

    //启动程序的执行
    private void action(){
        KeyAdapter k = new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode()==KeyEvent.VK_P){
                    if(state==RUNNING){
                        state = PAUSE;
                    }else if(state==PAUSE){
                        state = RUNNING;
                    }
                }
                if(state==RUNNING){
                    if(e.getKeyCode()==KeyEvent.VK_SPACE){
                        Bomb obj = ship.shootBomb();
                        bombs = Arrays.copyOf(bombs,bombs.length+1);
                        bombs[bombs.length-1] = obj;
                    }
                    if(e.getKeyCode()==KeyEvent.VK_LEFT){
                        ship.moveLeft(); //战舰左移
                    }
                    if(e.getKeyCode()==KeyEvent.VK_RIGHT){
                        ship.moveRight(); //战舰右移
                    }
                }
            }
        };
        this.addKeyListener(k);

        java.util.Timer timer = new Timer();
        int interval = 10;
        timer.schedule(new TimerTask() {
            public void run() {
                if(state==RUNNING){
                    submarineEnterAction();
                    moveAction();
                    bombBangAction();
                    mineBangAction();
                    outOfBoundsAction();
                    checkGameOverAction();
                    repaint();
                }
            }
        }, interval, interval);
    }

    //重写paint()画方法 g:画笔
    public void paint(Graphics g){
        Images.sea.paintIcon(null,g,0,0);
        ship.paintImage(g);
        for(int i=0;i<submarines.length;i++){
            submarines[i].paintImage(g);
        }
        for(int i=0;i<mines.length;i++){
            mines[i].paintImage(g);
        }
        for(int i=0;i<bombs.length;i++){
            bombs[i].paintImage(g);
        }
        g.drawString("SCORE: "+score,150,70);
        g.drawString("LIFE: "+ship.getLife(),400,70);

        if(state==GAME_OVER){
            Images.gameover.paintIcon(null,g,0,0);
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH+16, HEIGHT+39);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);

        world.action();
    }
}